'''
Created on Aug 10, 2012

@author: xding
'''

str_body = """<?xml version="1.0" encoding="UTF-8"?>
<gexf xmlns="http://www.gexf.net/1.2draft" 
    xmlns:viz="http://www.gexf.net/1.2draft/viz" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.gexf.net/1.2draft 
                        http://www.gexf.net/1.2draft/gexf.xsd" 
    version="1.2">
    <graph defaultedgetype="directed" mode="dynamic" timeformat="double" start = "10.0" end = "99.0">
        <nodes>%s
        </nodes>
        <edges>%s
        </edges>
    </graph>
</gexf>"""


gray   = (0xD0, 0xD0, 0xD0)
red    = (0xFF, 0x00, 0x00)
yellow = (0xFF, 0xFF, 0x00)
green  = (0x00, 0xFF, 0x00)
blue   = (0x00, 0x00, 0xFF)

import math
R = 50
def calcu_coor(x, y, i, ang):
    rad = ang / 180.0 * math.pi
    rx = x + R * math.cos(i * rad)
    ry = y + R * math.sin(i * rad)
    return rx, ry


def node_gexf_top(params):
    node_id, label, _pid, color, start, end = params
    color_str = """<viz:color r="%d" g="%d" b="%d" />""" % color
    pos_str = """<viz:position x="%f" y="%f" z="0.0" />""" % coor[node_id]
    spell_str = """<spell start="%f" end="%f" />""" % (start, end)
    return """
            <node id="%d" label="%s">
                <spells>
                    %s
                </spells>
                %s%s
            </node>""" % (node_id, label, spell_str, color_str, pos_str)


def node_gexf(params):
    node_id, label, pid, color, start, end = params
    if pid == 0: return node_gexf_top(params)
    color_str = """<viz:color r="%d" g="%d" b="%d" />""" % color
    x, y = calcu_coor(coor[pid][0], coor[pid][1], coor[node_id][0], coor[node_id][1])
    pos_str = """<viz:position x="%f" y="%f" z="0.0"/>""" % (x, y)
    spell_str = """<spell start="%f" end="%f" />""" % (start, end)
    return """
            <node id="%d" label="%s" pid="%d">
                <spells>
                    %s
                </spells>
                %s%s
            </node>""" % (node_id, label, pid, spell_str, color_str, pos_str)


edge_id = 0
def edge_gexf(label, source, target, spell_list):
    global edge_id
    edge_id = edge_id + 1
    color_str = """<viz:color r="%d" g="%d" b="%d" />""" % color[label]
    spell_str = ""
    for spell in spell_list:
        spell_str += """
                    <spell start="%f" end="%f" />""" % spell
    return """
            <edge id="%s" label="%s" source="%s" target="%s" weight="1">
                <spells>%s
                </spells>
                %s
            </edge>""" % (edge_id, label, source, target, spell_str, color_str)


stations = ["A", "B", "C", "D", "E", "F"]
routes = [["A", "B", "C", "D", "F"],    #1
          ["A", "B", "C", "E", "F"],    #2
]


walkin  = gray
walkout = gray
station = gray
target = yellow
origin = green
#node_id, label, pid, color, start, end
nodes = [(1, "A", 0, station, 10, 99), (2, "B", 0, station, 10, 99), (3, "C", 0, station, 10, 99),
         (4, "D", 0, station, 10, 99), (5, "E", 0, station, 10, 99), (6, "F", 0, station, 10, 99),
         
         #############################################
         
         (111, "A", 1, origin, 10, 99), (121, "A", 1, origin, 10, 99),
         (210, "B", 2, target, 10, 99), (220, "B", 2, target, 10, 99),
         (211, "B", 2, origin, 10, 99), (221, "B", 2, origin, 10, 99),
         (310, "C", 3, target, 10, 99), (320, "C", 3, target, 10, 99),
         (311, "C", 3, origin, 10, 99), (321, "C", 3, origin, 10, 99),
         (410, "D", 4, target, 10, 99),
         (411, "D", 4, origin, 10, 99),
                                        (520, "E", 5, target, 10, 99),
                                        (521, "E", 5, origin, 10, 99),
         (610, "F", 6, target, 10, 99), (620, "F", 6, target, 10, 99),
         
         ##############################################
         
         (100, "I", 1, walkin, 61, 99), 
         (300, "I", 3, walkin, 61, 99), (301, "O", 3, walkout, 61, 99),
         (400, "I", 4, walkin, 61, 99), (401, "O", 4, walkout, 61, 99),
         (500, "I", 5, walkin, 61, 99), (501, "O", 5, walkout, 61, 99),
                                        (601, "O", 6, walkout, 61, 99),
]

coor = {}
coor[1] = 0, 0
coor[2] = 150, 0
coor[3] = 300, 0
coor[4] = 410, 120
coor[5] = 410, -120
coor[6] = 510, 0
coor[111], coor[100], coor[121] = (1, 60), (3, 60), (5, 60)
coor[211], coor[210], coor[220], coor[221] = (1, 45), (3, 45), (5, 45), (7, 45)
coor[301], coor[311], coor[310], coor[300], coor[320], coor[321] = (0, 60), (1, 60), (2, 60), (3, 60), (4, 60), (5, 60)
coor[411], coor[400], coor[410], coor[401] = (0, 90), (1, 90), (2, 90), (3, 90)
coor[521], coor[500], coor[520], coor[501] = (0, 90), (1, 90), (2, 90), (3, 90)
coor[601], coor[610], coor[620] = (0, 60), (2, 60), (4, 60)


#label, source, target
edges = [("#", 1, 2), ("#", 2, 3), ("#", 3, 4),
         ("#", 3, 5), ("#", 4, 6), ("#", 5, 6),
         
         ##############################################
         
         ("R1", 111, 210), ("NT1", 210, 211), ("R1", 211, 310), ("NT1", 310, 311),
         ("R1", 311, 410), ("NT1", 410, 411), ("R1", 411, 610),
         
         ("R2", 121, 220), ("NT2", 220, 221), ("R2", 221, 320), ("NT2", 320, 321),
         ("R2", 321, 520), ("NT2", 520, 521), ("R2", 521, 620),
         
         ##############################################
         
         ("TF", 210, 221), ("TF", 220, 211),
         ("TF", 310, 321), ("TF", 320, 311),
         
         ##############################################
         
         ("WI", 100, 111), ("WI", 100, 121),
         ("WI", 300, 311), ("WI", 300, 321), ("WO", 310, 301), ("WO", 320, 301),
         ("WI", 400, 411),                   ("WO", 410, 401),
                           ("WI", 500, 521), ("WO", 520, 501),
                                             ("WO", 610, 601), ("WO", 620, 601),
         ("WW", 401, 500),
]

color = {}
color["#"] = gray
color["TF"] = color["WI"] = color["WO"] = gray
color["WW"] = blue
color["R1"] = color["NT1"] = red
color["R2"] = color["NT2"] = green


highlights = {
    (11, 20): [(edge[1], edge[2]) for edge in edges if edge[0] not in {"WI", "WO", "WW"}],
    
    (21, 30): [(111, 210), (210, 211), (211, 310), (310, 311), (311, 410), (410, 411), (411, 610)],
    (31, 40): [(121, 220), (220, 221), (221, 320), (320, 321), (321, 520), (520, 521), (521, 620)],
    (41, 50): [(111, 210), (210, 221), (221, 320), (320, 311), (311, 410), (410, 411), (411, 610)],
    (51, 60): [(121, 220), (220, 211), (211, 310), (310, 321), (321, 520), (520, 521), (521, 620)],
    
    (61, 65): [(edge[1], edge[2]) for edge in edges if edge[0] in {"WI", "WO", "NT1", "NT2", "TF"}],
    (66, 68): [(edge[1], edge[2]) for edge in edges if edge[0] not in {"WW"}],
    (69, 70): [(edge[1], edge[2]) for edge in edges if edge[0]],
    
    (70, 85): [(100, 111), (111, 210), (210, 211), (211, 310), (310, 311), (311, 410), (410, 401), 
               (401, 500), (500, 521), (521, 620), (620, 601)],
    #(36, 40): [(121, 220), (220, 211), (211, 310), (310, 321), (321, 520), (520, 521), (521, 620)],
}


highlight_spells = {}
for highligh_spell in highlights:
    highlight_edges = highlights[highligh_spell]
    start, end = highligh_spell
    #delta = min(1, float(end - start) / float(len(highlight_edges)))
    delta = (end - start) / len(highlight_edges)
    for highlight_edge in highlight_edges:
        highlight_spells.setdefault(highlight_edge, list()).append((start, start + delta))
        start += delta
    for highlight_edge in highlight_edges:
        highlight_spells.setdefault(highlight_edge, list()).append((start, end))

edges_str = ""
for edge in edges:
    spell_list = highlight_spells.get((edge[1], edge[2]), [])
    edges_str += edge_gexf(edge[0], edge[1], edge[2], spell_list)


nodes_str = "".join([node_gexf(node) for node in nodes])

import os
graph_out = str_body % (nodes_str, edges_str)
with open(os.environ['HOME'] + "\\output\\TimeDependent.gexf", 'w') as f:
    f.write(graph_out)

